package com.system.common.service.role.impl;

import com.system.common.bean.SnowflakeIdWorker;
import com.system.common.constant.BaseEnum;
import com.system.common.constant.RecordStatusConst;
import com.system.common.dao.purview.RolePurviewMapper;
import com.system.common.dao.role.RoleMapper;
import com.system.common.entity.purview.RolePurview;
import com.system.common.entity.purview.RolePurviewExample;
import com.system.common.entity.role.*;
import com.system.common.request.BaseReq;
import com.system.common.request.role.AssignPurReq;
import com.system.common.request.role.SaveRoleReq;
import com.system.common.response.BaseResp;
import com.system.common.response.PageResp;
import com.system.common.service.purview.PurviewService;
import com.system.common.service.role.RoleService;
import com.system.common.util.EntityUtil;
import com.system.common.util.PageHelperUtil;
import com.system.common.vo.role.AllRoleVo;
import com.system.common.vo.role.RoleVo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.system.common.constant.BaseEnum.*;
import static com.system.common.constant.BaseEnum.SUCCESS;

@Service
public class RoleServiceImpl implements RoleService {

    private static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private SnowflakeIdWorker idWorker;

    @Autowired
    private RolePurviewMapper rolePurviewMapper;

    @Override
    public PageResp search(SaveRoleReq req) {
        PageResp resp = new PageResp();
        RoleExample example = new RoleExample();
        RoleExample.Criteria criteria =example.createCriteria();
        if(StringUtils.isNoneBlank(req.getRoleName())){
            criteria.andRoleNameLike("%"+req.getRoleName()+"%");
        }else{
            req.setRoleName(null);
        }
        if(req.getId()!=null && req.getId()!=0){
            criteria.andIdEqualTo(req.getId());
        }
        if(req.getState()!=null){
            criteria.andStateEqualTo(req.getState());
        }
        Long totalRecord = roleMapper.countByExample(example);
        if(totalRecord==null || totalRecord==0){
            return PageHelperUtil.getDefaultPageHelper();
        }
        Integer pageSize = PageHelperUtil.getDefaultPageSize(req.getPageSize());
        Integer offset = PageHelperUtil.getOffset(Integer.valueOf(totalRecord.toString()),
                PageHelperUtil.getDefaultCurrentPage(req.getCurrentPage()),pageSize);
        List<RoleVo> data = roleMapper.selectByPage(req, pageSize, offset);
        resp.setCode(BaseEnum.SUCCESS.getCode());
        resp.setData(data);
        resp.setTotalRecord(totalRecord);
        return resp;
    }

    @Override
    public BaseResp saveRole(SaveRoleReq req) {
        BaseResp resp = new BaseResp();
        if(StringUtils.isBlank(req.getRoleName())){
            resp.setCode(BaseEnum.ROLE_SAVE_ARGS_ERROR.getCode());
            resp.setMsg(BaseEnum.ROLE_SAVE_ARGS_ERROR.getMsg());
            return resp;
        }

        if(req.getId()==null || req.getId()==0){
            Role role = getRoleByName(req.getRoleName());
            if(role!=null){
                resp.setCode(BaseEnum.ROLE_SAVE_ARGS_ERROR.getCode());
                resp.setMsg(BaseEnum.ROLE_SAVE_ARGS_ERROR.getMsg());
                return resp;
            }
            // 添加
            role = new Role();
            role.setId(idWorker.nextId());
            role.setRoleName(req.getRoleName());
            role.setRoleDescribe(req.getRoleDescribe());
            role.setCreateTime(new Date());
            role.setState(RecordStatusConst.ENABLE);
            roleMapper.insertSelective(role);
            resp.setCode(BaseEnum.SUCCESS.getCode());
            resp.setMsg(BaseEnum.SUCCESS.getMsg());
            return resp;
        }else{
            Role role = getRoleById(req.getId());
            if(role==null){
                resp.setCode(BaseEnum.RESULT_NULL.getCode());
                resp.setMsg(BaseEnum.RESULT_NULL.getMsg());
                return resp;
            }

            Role roleTmp = getRoleByName(req.getRoleName());
            if(roleTmp!=null && !Objects.equals(role.getId(),roleTmp.getId())){
                resp.setCode(BaseEnum.ROLE_SAVE_ARGS_ERROR.getCode());
                resp.setMsg(BaseEnum.ROLE_SAVE_ARGS_ERROR.getMsg());
                return resp;
            }
            // 更新
            RoleExample example = new RoleExample();
            RoleExample.Criteria criteria =example.createCriteria();
            criteria.andIdEqualTo(req.getId());
            role.setId(req.getId());
            role.setRoleName(req.getRoleName());
            role.setRoleDescribe(req.getRoleDescribe());
            role.setEditTime(new Date());
            role.setState(req.getState());
            roleMapper.updateByExampleSelective(role, example);
            resp.setCode(BaseEnum.SUCCESS.getCode());
            resp.setMsg(BaseEnum.SUCCESS.getMsg());
            return resp;
        }
    }

    @Override
    public BaseResp delRole(BaseReq request) {
        BaseResp resp = new BaseResp();
        if(request.getId()==null || request.getId()==0){
            resp.setCode(BaseEnum.ROLE_DEL_ARGS_ERROR.getCode());
            resp.setMsg(BaseEnum.ROLE_DEL_ARGS_ERROR.getMsg());
            return resp;
        }
        RoleExample example = new RoleExample();
        RoleExample.Criteria criteria =example.createCriteria();
        criteria.andIdEqualTo(request.getId());

        roleMapper.deleteByExample(example);
        resp.setCode(BaseEnum.SUCCESS.getCode());
        resp.setMsg(BaseEnum.SUCCESS.getMsg());
        return resp;
    }

    @Override
    public List<Long> getRoleIdByPersonId(Long id) {
        if(id==null || id==0){
            return null;
        }
        List<Long> roleIds = roleMapper.selectRoleIds(id);
        return roleIds;
    }

    @Override
    public PageResp queryAllRole(BaseReq req) {
        PageResp resp = new PageResp();
        if(req.getId()==null || req.getId()==0){
            resp.setCode(ROLE_DEL_ARGS_ERROR.getCode());
            resp.setMsg(ROLE_DEL_ARGS_ERROR.getMsg());
            return resp;
        }
        List<AllRoleVo> allRoleList = roleMapper.selectAllRole();
        if(CollectionUtils.isEmpty(allRoleList)){
            resp.setCode(RESULT_NULL.getCode());
            resp.setMsg("没有角色可添加");
            return resp;
        }
        List<Long> personRoleId = roleMapper.selectRoleIds(req.getId());
        if(CollectionUtils.isEmpty(personRoleId)){
            resp.setCode(SUCCESS.getCode());
            resp.setData(allRoleList);
            resp.setMsg("成功");
            return resp;
        }

        for(Long id : personRoleId){
            for(AllRoleVo allRole : allRoleList){
                if(Objects.equals(id, allRole.getId())){
                    allRole.setUse(Boolean.TRUE);
                }
            }
        }

        resp.setCode(SUCCESS.getCode());
        resp.setData(allRoleList);
        resp.setMsg("成功");
        return resp;
    }

    @Override
    @Transactional
    public BaseResp assignPur(AssignPurReq req) {
        BaseResp resp = new BaseResp();
        if(req.getId()==null || req.getId()==0){
            resp.setCode(ROLE_DEL_ARGS_ERROR.getCode());
            resp.setMsg(ROLE_DEL_ARGS_ERROR.getMsg());
            return resp;
        }
        if(req.getPurviewArr()==null || req.getPurviewArr().length==0){
            resp.setCode(ARGS_ERROR.getCode());
            resp.setMsg(ARGS_ERROR.getMsg());
            return resp;
        }
        // 删除之前分配的权限
        RolePurviewExample purviewExample = new RolePurviewExample();
        purviewExample.createCriteria()
                .andRoleIdEqualTo(req.getId());
        rolePurviewMapper.deleteByExample(purviewExample);

        for(Long purId : req.getPurviewArr()){
            RolePurview rolePurview = new RolePurview();
            rolePurview.setId(idWorker.nextId());
            rolePurview.setRoleId(req.getId());
            rolePurview.setPurviewId(purId);
            rolePurview.setCreateTime(new Date());
            rolePurviewMapper.insertSelective(rolePurview);
        }
        resp.setCode(SUCCESS.getCode());
        resp.setMsg(SUCCESS.getMsg());
        return resp;
    }

    private Role getRoleByName(String name){
        RoleExample example = new RoleExample();
        example.createCriteria()
                .andRoleNameEqualTo(name);

        List<Role> roleList = roleMapper.selectByExample(example);
        return EntityUtil.getFirst(roleList);
    }

    private Role getRoleById(Long id){
        RoleExample example = new RoleExample();
        example.createCriteria()
                .andIdEqualTo(id);

        List<Role> roleList = roleMapper.selectByExample(example);
        return EntityUtil.getFirst(roleList);
    }
}
